import {
  HYEventStore
} from "hy-event-store"
import {
  getSongDetail,
  getSongLyric
} from "../service/api_player"
import {
  parseLyric,
  randomNumber
} from "../utils/index"

// 前台播放 AudioContext
// const audioContext = wx.createInnerAudioContext()
// 后台播放 
const audioContext = wx.getBackgroundAudioManager()

const playerStore = new HYEventStore({
  state: {
    id: 0,
    currentSong: {},
    durationTime: 0,
    lyricInfos: [],

    currentTime: 0,
    currentLyricIndex: 0,
    currentLyricText: "",

    playModeIndex: 0, // 0：循环播放 1：单曲循环 2：随机播放
    isPlaying: false,

    playListSongs: [],
    playListIndex: 0,

    isFirstPlay: true,
    isStoping: false
  },
  actions: {
    // 1.audioContext 音乐播放（调前准备&播放）-isRefresh 是否需要强制刷新（重头播放）
    playMusicWithSongIdAction(ctx, {
      id,
      isRefresh = false
    }) {
      // 当是同一首歌的时候，不要从头播放（有时候会传Sting）
      if (ctx.id == id && !isRefresh) {
        this.dispatch("changeMusicPlayStatusAction")
        return
      }
      ctx.id = id
      // 0.修改播放的状态
      ctx.isPlaying = true
      // 数据请求到来前，清空原有数据
      ctx.currentSong = {}
      ctx.durationTime = 0
      ctx.lyricInfos = []

      ctx.currentTime = 0
      ctx.currentLyricIndex = 0
      ctx.currentLyricText = ""

      // 1.网络请求抽取，根据id请求数据
      // 请求歌曲详情
      getSongDetail(id).then(res => {
        // console.log(res);
        ctx.currentSong = res.songs[0]
        ctx.durationTime = res.songs[0].dt
        // 同时设置后台播放真实 title
        audioContext.title = res.songs[0].name
      })
      // 请求歌词数据
      getSongLyric(id).then(res => {
        // console.log(res.lrc.lyric);
        const lyricString = res.lrc.lyric
        const lyrice = parseLyric(lyricString)
        // console.log(lyrice);
        ctx.lyricInfos = lyrice
      })

      // 2.调用audioContext播放对应id歌曲 抽取
      // 播放先停止上一首（ios会出现个别手机不回调onCanplay，因此取消拨前暂停）
      // audioContext.stop()
      audioContext.src = `https://music.163.com/song/media/outer/url?id=${id}.mp3`
      // 歌曲播放时，就必须有，title，暂时设置后台播放 title
      audioContext.title = id
      // 自动播放
      audioContext.autoplay = true

      // 3.监听audioContext一些事件(监听优化，用的都是一个audioContext除第一次监听，其他不需要监听)
      if (ctx.isFirstPlay) {
        this.dispatch("setupAudioContextListenerAction")
        ctx.isFirstPlay = false
      }

    },

    // 2.播放后监听播放信息（时间&进度）
    setupAudioContextListenerAction(ctx) {
      // 1.监听歌曲可以播放（ios会出现个别手机不回调，因此取消拨前暂停）
      audioContext.onCanplay(() => {
        audioContext.play()
      })

      // 2.监听播放时间变化
      audioContext.onTimeUpdate(() => {
        // 1.获取播放当前进度时间（API获取到的是秒s，需要转成毫秒ms，用于界面显示）Math.ceil
        const currentTime = audioContext.currentTime * 1000

        // 2.根据当前时间修改currentTime
        ctx.currentTime = currentTime

        // 3.根据当前时间去查找播放的歌词
        // 当没有歌词，直接返回
        if (!ctx.lyricInfos.length) return
        let i = 0
        for (; i < ctx.lyricInfos.length; i++) {
          // 获取当前索引歌词对象
          const lyricInfo = ctx.lyricInfos[i]
          if (currentTime < lyricInfo.time) {
            break
          }
        }
        // 设置当前歌词的索引和内容
        const currentIndex = i - 1
        if (ctx.currentLyricIndex !== currentIndex) {
          const currentLyricInfo = ctx.lyricInfos[currentIndex]
          ctx.currentLyricIndex = currentIndex
          ctx.currentLyricText = currentLyricInfo.text
        }
      })

      // 3.监听歌曲是否播放完毕
      audioContext.onEnded(() => {
        this.dispatch("changeNewMusicAcion")
      })

      // 监听音乐暂停/播放（解决后台按钮与详情页同步问题）
      // 播放状态
      audioContext.onPlay(() => {
        ctx.isPlaying = true
      })
      // 暂停状态
      audioContext.onPause(() => {
        ctx.isPlaying = false
      })
      // 停止状态
      audioContext.onStop(() => {
        ctx.isPlaying = false
        ctx.isStoping = true
      })
    },

    // 3.播放&暂停
    changeMusicPlayStatusAction(ctx, isPlaying = true) {
      ctx.isPlaying = isPlaying
      // 后台停止掉之后，点击播放，继续播
      if (ctx.isPlaying && ctx.isStoping) {
        audioContext.src = `https://music.163.com/song/media/outer/url?id=${ctx.id}.mp3`
        audioContext.title = ctx.currentSong.name
        audioContext.startTime = ctx.currentTime / 1000
        ctx.isStoping = false
      }
      ctx.isPlaying ? audioContext.play() : audioContext.pause()
    },

    // 4.上一首和下一首&播放模式
    changeNewMusicAcion(ctx, isNext = true) {
      // 1.获取当前索引
      let index = ctx.playListIndex
      let newIndex = 0

      // console.log("index:", index);
      // 2.根据不同的播放模式(索引)，获取下一首歌的索引
      switch (ctx.playModeIndex) {
        case 0: // 顺序播放
          newIndex = isNext ? index + 1 : index - 1
          if (newIndex === -1) newIndex = ctx.playListSongs.length - 1
          if (newIndex === ctx.playListSongs.length) newIndex = 0
          break
        case 1: // 单曲循环（不做处理）
          break
        case 2: // 随机播放
          newIndex = randomNumber(index, ctx.playListSongs.length)
          break
      }
      // console.log("newIndex:", newIndex);
      // 3.获取歌曲
      let currentSong = ctx.playListSongs[newIndex]
      // 如果 currentSong为空，没有歌（直接从播放页启动），让他播放store中存的歌
      if (!currentSong) {
        currentSong = ctx.currentSong
      } else {
        // 更新记录最新的索引
        ctx.playListIndex = newIndex
      }

      // 4.调用 audioContext 播放歌曲
      this.dispatch("playMusicWithSongIdAction", {
        id: currentSong.id,
        isRefresh: true
      })
    }
  }
})


export {
  audioContext,
  playerStore
}